package com.fanxuankai.boot.monitor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author fanxuankai
 */
public class MonitorTaskConfigurer implements SchedulingConfigurer, InitializingBean, DisposableBean {
    @Autowired(required = false)
    private List<Monitor> monitors = Collections.emptyList();
    @Resource
    private Notifier<Message> notifier;
    private static final Logger LOGGER = LoggerFactory.getLogger(MonitorTaskConfigurer.class);

    @Override
    public void configureTasks(@NonNull ScheduledTaskRegistrar taskRegistrar) {
        monitors.forEach(monitor -> taskRegistrar.addTriggerTask(() -> {
            try {
                monitor.exec();
            } catch (Throwable e) {
                LOGGER.error("监控执行异常: {}", monitor.title(), e);
                Message message = new Message();
                message.setTitle(monitor.title());
                message.setDescription(e.getMessage());
                notifier.notice(message);
            }
        }, triggerContext -> new CronTrigger(monitor.cron())
                .nextExecutionTime(triggerContext)));
    }

    @Override
    public void afterPropertiesSet() {
        notice("监控上线");
    }

    @Override
    public void destroy() {
        notice("监控下线");
    }

    private void notice(String title) {
        if (monitors.isEmpty()) {
            return;
        }
        Message message = new Message();
        message.setTitle(title);
        message.setContents(monitors.stream()
                .map(o -> o.title() + ": " + o.cron())
                .collect(Collectors.toList()));
        notifier.notice(message);
    }
}
